package handlers

import (
	"go.uber.org/zap"
	"venus/conf"
	"venus/servers/game/cached"
	"venus/servers/game/logics"
	"venus/servers/game/objects"
	"venus/servers/pub/pub_mgr"
	"venus/service/sv_tcp/znet"
	"venus/service/sv_tcp/znet/zpb"
	"venus/service/sv_tcp/znet/ztcp"
	"venus/util/zlog"
	"venus/util/zmisc"
	"venus/util/zredis"
	"venus/util/ztime"
)

// bindConn 绑定客户端连接
func bindConn(player *objects.Player, conn *ztcp.TcpConnection) {
	player.Conn = conn
	conn.BindObj = player
	conn.BindUid = player.Pid
}

// playerLogin 玩家登录
func playerLogin(player *objects.Player) {
	player.TimeLogin = ztime.UnixMilli()
	cached.SetPlayer(player)
}

// C2GPlayerLogin 玩家登入
func C2GPlayerLogin(request *znet.Request) int {
	zlog.Debug("C2GPlayerLogin")

	zlog.Debug("C2GPlayerLogin", zap.Int("GetGoroutineID", zmisc.GetGoroutineID()))

	req := &zpb.C2GPlayerLogin{}
	rsp := &zpb.G2CPlayerLogin{}
	if !request.GetPb(req) {
		return 1
	}

	_, hasPlayer := GetPLayer(request)
	if hasPlayer {
		return request.Send(rsp, conf.EProtocolResult重复登录)
	}

	rsp.Puid = logics.GetUuidPid(req.UserId)
	// 无数据 等待创建
	if rsp.Puid == 0 {
		return request.SendSuccess(rsp)
	}
	player := cached.GetPlayer(rsp.Puid)
	if player != nil {
		// 判断顶号
		if player.Conn.ConnID != request.Conn.ConnID {
			var msgReplace = &zpb.G2CPlayerReplace{}
			player.Conn.SendSuccess(msgReplace)
		}
	} else {
		player = objects.NewPlayer(rsp.Puid)
		zredis.HGetData(player)
		if player.Pid == 0 {
			return request.Send(rsp, conf.EProtocolResult服务器数据库异常)
		}
	}

	bindConn(player, request.Conn)
	playerLogin(player)

	return request.SendSuccess(rsp)
}

// C2GPlayerCreate 玩家创建
func C2GPlayerCreate(request *znet.Request) int {
	zlog.Debug("C2GPlayerCreate")

	req := &zpb.C2GPlayerCreate{}
	rsp := &zpb.G2CPlayerCreate{}
	if !request.GetPb(req) {
		return 1
	}

	_, hasPlayer := GetPLayer(request)
	if hasPlayer {
		return request.Send(rsp, conf.EProtocolResult重复登录)
	}

	if req.Name == "8i9o0p" {
		req.Name = pub_mgr.RandomName()
	}

	eCode := logics.CheckPlayerName(req.Name)
	if eCode != 0 {
		return request.Send(rsp, eCode)
	}

	// 判断重名
	pidCheckName := logics.GetNamePid(req.Name)
	if pidCheckName != 0 {
		return request.Send(rsp, conf.EProtocolResult名字已经被使用)
	}

	rsp.Puid = pub_mgr.CreatePid()
	player := objects.NewPlayer(rsp.Puid)
	player.Uuid = req.UserId
	player.Conn = request.Conn

	logics.PlayerCreate(player, req)

	logics.SetUuidPid(player.Uuid, player.Pid)
	logics.SetNamePid(player.Name, player.Pid)

	bindConn(player, request.Conn)
	playerLogin(player)

	zredis.HSetData(player)

	return request.SendSuccess(rsp)
}
